<script setup lang="ts">
import { ref, onMounted, watch, nextTick } from "vue";

interface Props {
  modelValue: string;
  placeholder?: string;
  class?: string;
  autofocus?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: "",
  class: "",
  autofocus: false,
});

const emit = defineEmits<{
  "update:modelValue": [value: string];
  enter: [];
  blur: [];
  esc: [];
}>();

const textareaRef = ref<HTMLTextAreaElement | null>(null);

// 自动调整高度
function autoResize() {
  if (textareaRef.value) {
    textareaRef.value.style.height = "auto";
    textareaRef.value.style.height = textareaRef.value.scrollHeight + "px";
  }
}

// 处理输入
function handleInput(event: Event) {
  const target = event.target as HTMLTextAreaElement;
  emit("update:modelValue", target.value);
  autoResize();
}

// 处理回车键
function handleKeyEnter() {
  emit("enter");
}

// 处理失焦
function handleBlur() {
  emit("blur");
}

// 处理 ESC 键
function handleEsc() {
  emit("esc");
}

// 监听 modelValue 变化，自动调整高度
watch(
  () => props.modelValue,
  () => {
    nextTick(() => {
      autoResize();
    });
  }
);

// 组件挂载后自动调整高度
onMounted(() => {
  autoResize();
  if (props.autofocus && textareaRef.value) {
    textareaRef.value.focus();
  }
});

// 暴露方法供父组件调用
defineExpose({
  focus: () => {
    if (textareaRef.value) {
      textareaRef.value.focus();
      autoResize();
    }
  },
  blur: () => {
    if (textareaRef.value) {
      textareaRef.value.blur();
    }
  },
});
</script>

<template>
  <textarea
    ref="textareaRef"
    :value="modelValue"
    :placeholder="placeholder"
    :class="props.class"
    @input="handleInput"
    @keyup.enter.exact="handleKeyEnter"
    @keyup.esc="handleEsc"
    @blur="handleBlur"
    rows="1"
  />
</template>

<style scoped>
textarea {
  font-family: inherit;
  resize: none;
  line-height: 1.5;
  overflow: hidden;
}
</style>
